import { useState, useEffect } from "react";
import Button from "@mui/material/Button";
import Dialog from "@mui/material/Dialog";
import DialogContent from "@mui/material/DialogContent";
import DialogTitle from "@mui/material/DialogTitle";
import DialogActions from "@mui/material/DialogActions";
import ListItemButton from "@mui/material/ListItemButton";
import Stack from "@mui/material/Stack";
import Accordion from "@mui/material/Accordion";
import AccordionDetails from "@mui/material/AccordionDetails";
import AccordionSummary from "@mui/material/AccordionSummary";
import TextField from "@mui/material/TextField";
import DualList from "./DualList";
import DualListPart from "./DualListPart";
import CopyToClipboard from "react-copy-to-clipboard";
import databaseApis from "../apis/indexedDBs.mjs";
import { GM_registerMenuCommand } from "tm";
import {
  titleFont,
  firstDlg,
  secondDlg,
  codeStyle,
  buttonFont,
} from "../data.mts";

export default function DatabaseDialog(properties: { inner?: HTMLElement }) {
  const [open, setOpen] = useState(false);
  const [data, setData] = useState<
    {
      name: string;
      version?: number;
      tables: {
        name: string;
        kvs: Record<string | number, unknown>;
      }[];
    }[]
  >([]);
  const [content, setContent] = useState("");
  const [vOpen, setvOpen] = useState(false);
  const [vKey, setvKey] = useState("");

  const updateData = () => {
    return databaseApis
      .query()
      .then((result) => {
        setData(result.data);
        return result.data.length > 0;
      })
      .catch(() => {
        setOpen(false);
      });
  };

  const handleCloseV = () => {
    setvOpen(false);
    setvKey("");
    setContent("");
  };

  useEffect(() => {
    updateData()
      .then((have) => {
        if (have) {
          GM_registerMenuCommand("indexedDB UI", () => {
            setOpen(true);
          });
        }
      })
      .catch(() => {
        setOpen(false);
      });
  }, []);

  return (
    <>
      <Dialog
        open={open}
        onClose={() => {
          setOpen(false);
        }}
        sx={firstDlg}
        container={properties.inner}
      >
        <DialogTitle sx={titleFont}>
          <Stack
            direction="row"
            justifyContent="space-between"
            alignItems="center"
            spacing={10}
          >
            indexedDB
            <Button
              variant="contained"
              color="error"
              size="small"
              sx={{ fontSize: 13 }}
              onClick={() => {
                databaseApis
                  .clear()
                  .then(() => {
                    void updateData();
                  })
                  .catch(() => {
                    alert("清空失败");
                  });
              }}
            >
              清空全部
            </Button>
          </Stack>
        </DialogTitle>
        <DialogContent
          sx={{
            display: "flex",
            flexDirection: "column",
          }}
        >
          {data.map((base, index) => (
            <Accordion key={`b${base.name}`}>
              <AccordionSummary>
                <Stack
                  direction="row"
                  justifyContent="space-between"
                  alignItems="center"
                  spacing={2}
                >
                  <code
                    style={{
                      maxWidth: "40vw",
                      ...codeStyle,
                    }}
                  >
                    {`${String(index + 1)}/${String(data.length)} ${base.name} v${String(base.version ?? 1)}`}
                  </code>
                  <Button
                    variant="contained"
                    color="error"
                    size="small"
                    sx={{ fontSize: 13 }}
                    onClick={() => {
                      databaseApis
                        .remove(base.name)
                        .then(() => {
                          void updateData();
                        })
                        .catch(() => {
                          void updateData();
                        });
                    }}
                  >
                    删除
                  </Button>
                </Stack>
              </AccordionSummary>
              <AccordionDetails>
                <DualList>
                  {base.tables.map((table, index) => (
                    <DualListPart
                      key={"t" + table.name}
                      header={`${String(index + 1)}/${String(base.tables.length)} ${table.name}`}
                    >
                      {Object.keys(table.kvs).map((key) => (
                        <ListItemButton
                          key={key}
                          onClick={() => {
                            setvKey(key);
                            setContent(JSON.stringify(table.kvs[key], null, 2));
                            setvOpen(true);
                          }}
                        >
                          <code style={codeStyle}>{key}</code>
                        </ListItemButton>
                      ))}
                    </DualListPart>
                  ))}
                </DualList>
              </AccordionDetails>
            </Accordion>
          ))}
        </DialogContent>
      </Dialog>
      <Dialog
        open={vOpen}
        onClose={handleCloseV}
        sx={secondDlg}
        container={properties.inner}
      >
        <DialogTitle
          sx={{
            fontSize: 15,
            wordBreak: "break-all",
          }}
        >
          {vKey}
        </DialogTitle>
        <DialogContent>
          <TextField
            margin="dense"
            multiline
            rows={7}
            label="内容"
            type="text"
            fullWidth
            variant="outlined"
            value={content}
            InputProps={{
              readOnly: true,
              sx: {
                fontFamily: "monospace",
              },
            }}
          />
        </DialogContent>
        <DialogActions>
          <CopyToClipboard text={content}>
            <Button sx={buttonFont}>复制</Button>
          </CopyToClipboard>
          <Button onClick={handleCloseV} sx={buttonFont}>
            关闭
          </Button>
        </DialogActions>
      </Dialog>
    </>
  );
}
